package com.gui.spring.aop.springProxy;

import cn.hutool.core.util.RandomUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.util.Arrays;

public class SpringSelectProxy {

    public static void main(String[] args) {
        /**
         * Spring 选择代理
         *  1、proxyTargetClass = false，目标类实现了接口，则选择 JDK 动态代理
         *  2、proxyTargetClass = false，目标类没有实现接口，则选择 CGLIB 动态代理
         *  3、proxyTargetClass = true，不管目标类有没有实现接口，都选择 CGLIB 动态代理
         */

        ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        System.out.println("=============================================");
        EnableAspectJAutoProxy annotation = Config.class.getAnnotation(EnableAspectJAutoProxy.class);
        boolean proxyTargetClass = annotation.proxyTargetClass();
        System.out.println("proxyTargetClass:" + proxyTargetClass);
        ITargetService targetService1 = context.getBean(ITargetService.class);
        System.out.println(targetService1.getClass());
        TargetService2 targetService2 = context.getBean(TargetService2.class);
        System.out.println(targetService2.getClass());


    }


    static interface ITargetService {
        public String foo(String text);
    }

    @Component
    static class TargetService1 implements ITargetService {

        @Override
        public String foo(String text) {
            System.out.println("TargetService1 foo()");
            return RandomUtil.randomString(6);
        }
    }

    @Component
    static class TargetService2 {

        public String foo(String text) {
            System.out.println("TargetService2 foo()");
            return RandomUtil.randomString(6);
        }
    }

    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @ComponentScan("com.gui.spring.aop.springProxy")
    @Configuration
    static class Config{

    }

    @Component
    @Aspect
    static class LogAspect{

        @Around("execution(* foo(..))")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
            Object[] args = joinPoint.getArgs();
            System.out.println("环绕前置，打印入参：" + Arrays.toString(args));
            Object result = joinPoint.proceed();
            System.out.println("环绕后置，打印返回值：" + result);
            return result;
        }

    }
}
